<!-- 模板 -->
<template>
  <div class="common-layout">
    <el-container style="background-color: darkcyan">
      <el-header>Header</el-header>
      <el-container style="background-color: aqua">
        <el-aside width="200px">Aside</el-aside>
        <el-main style="background-color: salmon">Main</el-main>
      </el-container>
    </el-container>
  </div>

  <div class="mainContainer">
    <h1>模板语法</h1>
    <div>姓名； {{ name }}</div>
    <div> 年龄：{{ age + 1 }}</div>
    <div> 爱好：{{ hobbies[0] }}-{{ hobbies[1] }}-{{ hobbies[2] }}</div>
    <!-- <div v-for="hobbies in hobbies"> {{ hobbies }}</div> -->
    <div> 朋友：{{ friend.name }}、年龄：{{ friend.age }}</div>

    <p v-if="awesome">看看我能不能看见</p>
    <p v-else>他不出来我就出来</p>
    <!-- <p v-else-if="awesome===true">他不出来我就出来</p> -->
    <p v-show="true">我是v-show</p>


    <!-- <ul>
  <li v-for="(itme,index) in riends">{{ itme }}- {{ index }}</li>
</ul> -->
    <ul>
      <!-- 遍历时尽量设置key,提高渲染效率,因为vue会根据key值进行对比，如果key值相同，则不会重新渲染 -->
      <li v-for="itme in riends" :id="itme.name">{{ itme.name }}- {{ itme.age }}</li>
    </ul>
    <button @click="addFriend">添加一个朋友</button>

    <button @click="updataFriend">修改一个朋友</button>
    <button @click="deletefriend">点击我删除</button>

    <h3>事件</h3>
    <button @click="change">点击我</button>


    <h3>样式</h3>

    <div :class="classObject">对象；来看看我样式</div>
    <div :class="classArr">数组；来看看我样式</div>

    <div :style="styleObject">这个是内联样式</div>

    <button @click="renewStule">class对象；恢复到原来的样式</button>
    <button @click="renewarr">class 数组 ；恢复到原来的样式</button>
    <button @click="styleStule">内联样式 对象 ；恢复到原来的样式</button>

    <h2>表单</h2>
    <h3>用户的整体信息：{{ userInfoss }}</h3>
    <h3>用户的整体信息：{{ userInfoss }}</h3>
    <h3>用户的整体信息：{{ userInfoss }}</h3>

    <div>
      <!-- 昵称：<input type="text" :value="nickName"  > 原来-->
      <!-- v-model:双向绑定：取代value， -->
      昵称：<input type="text" v-model="data.nickName">
      <button @click="printData">拿到表单中的数据</button>
      <button @click="updataData">修改表单中的数据</button>
      <br>
      性别：
      <!-- input:id与label的for属性值相同，点击label时，会自动选中对应的input -->
      <!-- 两个name值相同，表示这两个input是互斥的，只能选中一个 -->
      <input type="radio" id="man" name="sex" value="man" v-model="data.sex" />
      <label for="man">男</label>
      <input type="radio" id="woman" name="sex" value="woman" v-model="data.sex" />
      <label for="woman">女</label>
      <button @click="sexData">打印性别</button>

      <br>
      兴趣：
      <input type="checkbox" id="sing" value="sing" v-model="data.checkedNames" />
      <label for="sing">sing</label>

      <input type="checkbox" id="dance" value="dance" v-model="data.checkedNames" />
      <label for="dance">dance</label>

      <input type="checkbox" id="rap" value="乒乓球" v-model="data.checkedNames" />
      <label for="rap">rap</label>
      <button @click="hobbyData">打印爱好</button>


      <br>
      城市：
      <select v-model="data.city">
        <!-- disabled：禁用，选过的不能再次选择 -->
        <option disabled value="">不能选</option>
        <option value="南宁">南宁</option>
        <option value="柳州">柳州</option>
        <option value="桂林">桂林</option>
      </select>
      <button @click="cityData">打印城市</button>

      <button @click="qingkong">清空</button>
      <button @click="longds">打印模拟接收到的数据</button>


      <!-- 监听器 -->
      <h3>监听器</h3>
      购买数量：{{ count }}
      <br>
      <!-- <button v-if="isShowSub" disabled >-</button>
<button    v-if="!isShowSub" @click="sub">-</button>

<button  v-if="isShowadd" disabled >+</button>
<button  v-if="!isShowadd" @click="add">+</button> -->


      <!-- 简便写法 -->
      <button :disabled="isShowSubs" @click="sub">-</button>
      <button :disabled="isShowadds" @click="add">+</button>

    </div>
  </div>
  <!-- 子组件 -->
  <!-- ref:获取子组件中的数据 -->
  <Mycomponents ref="childDatas" placeholder="请输入" :riends="riends" title="我是父组件给的字符串" :parentDatas="data">
  </Mycomponents>

  <button @click="getchildDatas">获取子组件中的数据</button>



  <div>
    <h2>路由</h2>
    <button @click="toNotice">去通知</button>
    <div style="display: flex;">
      <div style=" background-color: pink;width: 200px ">
        <ul>
          <li>
            <!-- 可以通过url传参 -->
            <RouterLink to="/emloyee?id=123">用户管理</RouterLink>

          </li>
          <li>
            <!-- <RouterLink :to="{path:'/roleInfo'}">角色管理</RouterLink> -->
            <!-- abc是值 ，值的名字在main文件配置路由中定义-->
            <RouterLink to="/roleInfo/abc">角色管理</RouterLink>


          </li>
          <li>
            <!-- replace:不记录历史记录,就会覆盖掉之前的记录，就是返回上上给页面，不会返回到上一次的页面 -->

            <!-- Pinia:状态管理 ，当多个组件需要相互传值，类似于浏览器缓存效果-->
            <RouterLink replace :to="{ name: 'on' }">通知管理</RouterLink>

          </li>
        </ul>
      </div>

      <div style=" background-color:green ;width: 100%">
        <!-- RouterView:显示路由地址组件 的标签-->
        <RouterView></RouterView>
      </div>
    </div>


  </div>


  <!-- 插槽 -->
  <div>
    <h2>插槽</h2>
    <div>
      <Content>
        <!-- <template v-slot:header>
          <ul>
            <li>头</li>
            <li>头</li>
            <li>头</li>

          </ul>
        </template>
        <template #:body>
          <ul>
            <li>身体</li>
            <li>身体</li>
            <li>身体</li>

          </ul>
        </template> -->

      <template v-slot:body="childDatas">
        <button @click="slotBtn(childDatas.item,childDatas.myName)">我是按钮</button>
        <span>我是插槽的内容，{{ childDatas }}</span>
      </template>
      </Content>
    </div>

  </div>

</template>




<!-- 脚本 -->
<script setup lang="ts">
//组件已经创建完毕
console.log("组件已经创建完毕");

//插槽组件引入s
import Content from '@/components/Content.vue'
//插槽按钮点击事件
//v-slot:body="childDatas";是插槽传过来的数据，是一个对象，可以点出对象中的属性
function slotBtn(childDatas, myName) {
console.log(childDatas);
console.log(myName);

}

import { useRoute, useRouter } from "vue-router";//useRoute:获取路由信息，useRouter:获取路由对象
//引入子组件
import Mycomponents from "./components/Mycomponents.vue";

//引入
import { ref, reactive, computed, watch, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from "vue"//导入ref响应式
import { defineStore } from "pinia";

//onBeforeMount:组件渲染之前，也就是DOM还没有渲染之前要执行的代码
//onMounted ：组件渲染之后，也就是DOM已经渲染后要执行的代码，最多使用，在加载完数据后，调用接口，获取数据
//onBeforeUpdate:组件更新之前，也就是DOM还没有更新之前要执行的代码
//onUpdated ：组件更新之后，也就是DOM已经更新后要执行的代码
//onBeforeUnmount:组件卸载之前，也就是DOM还没有卸载之前要执行的代码
//onUnmounted ：组件卸载之后，也就是DOM已经卸载后要执行的代码

//导入ref响应式:一般用于基本数据类型
//reactive()：创建一个响应式数据，返回一个对象，对象中存储的是响应式数据：一般用于对象
//computed()：计算属性,他是一个函数，返回一个值，这个值是响应式的
//watch()：监听器，监听一个响应式数据，当这个数据发生变化时，执行相应的操作
onBeforeMount(() => {
  console.log("组件渲染之前，也就是DOM还没有渲染之前要执行的代码");
})
onMounted(() => {
  console.log("组件渲染之后，也就是DOM已经渲染后要执行的代码");
})
onBeforeUpdate(() => {
  console.log("组件更新之前，也就是DOM还没有更新之前要执行的代码");
})
onUpdated(() => {
  console.log("组件更新之后，也就是DOM已经更新后要执行的代码");
});
onBeforeUnmount(() => {
  console.log("组件卸载之前，也就是DOM还没有卸载之前要执行的代码");
})
onUnmounted(() => {
  console.log("组件卸载之后，也就是DOM已经卸载后要执行的代码")
})

let name = "张三";
let age = 18;
let hobbies = ["篮球", "足球", "乒乓球"];
let friend = {
  name: "李四",
  age: 20
}
//是否显示
let awesome = ref(false);
//ref()：创建一个响应式数据，返回一个对象，对象中有一个value属性，存储的是响应式数据


//for in 遍历
let riends = ref([{ id: 0, name: "gggg", age: 20 }, { id: 1, name: "王sss五", age: 21 }, { id: 2, name: "赵六", age: 22 }]);


//删除一个
function deletefriend() {
  riends.value.shift()//删除第一个
  // riends.value.pop()//删除最后一个

  console.log(riends);
}
//修改一个朋友
function updataFriend() {
  riends.value[0] = {
    id: 0,
    name: "麻瓜",
    age: 11
  }
}
//添加一个朋友
function addFriend() {
  // riends.value.push({id:3,name:"王麻子",age:30})//在数组最后中添加一个对象
  riends.value.unshift({ id: 3, name: "王麻子", age: 30 })//在数组最前面添加一个对象

}


//点击事件
function change() {
  console.log("我被点击了");
  awesome.value = !awesome.value
  console.log(awesome);
}


// class与style绑定
// V-bigint:class

//样式对象
let classObject = ref(({ //true:显示，false：隐藏
  blackFont: true,
  whiteBackground: true
}))

//恢复到原来的样式
function renewStule() {
  classObject.value.blackFont = !classObject.value.blackFont,
    classObject.value.whiteBackground = !classObject.value.whiteBackground
  console.log(classObject);
}
//绑定数组形式

let classArr = ref(['blackFont',
  'whiteBackground'])

function renewarr() {
  if (classArr.value.length > 0) {
    classArr.value = []
  } else {
    classArr.value = ['blackFont',
      'whiteBackground']
  }
}


// style绑定内联样式
//键值对形式
let styleObject = reactive({
  'color': "red",//字体颜色是红色
  'fontSize': "10px",//字体为40px
  'padding': '10px'//内边距为10px

})

function styleStule() {
  styleObject.color = "black"
}





//模拟接收到的数据
let res = {
  code: 200,
  data: {
    nickName: "张三",
    sex: "woman",
    age: 18,
    checkedNames: ["乒乓球"],
    city: "南宁"
  }
}

let data = ref(res.data)



//表单
// 文本输入框  <!-- input:id与label的for属性值相同，点击label时，会自动选中对应的input -->
let nickName = ref("张三")

//拿到表单中的数据
function printData() {
  console.log(nickName.value);
}
function updataData() {

  nickName.value = "李四"
}

//单选框 必须要有value值
let sex = ref("")

function sexData() {
  console.log(sex.value);
}

//多选框
let checkedNames = ref([])

//多选框
function hobbyData() {
  console.log(checkedNames.value);
}



//下拉框
let city = ref("")

function cityData() {
  console.log(city.value);
}

//清空
function qingkong() {

  // nickName.value="",
  // sex.value="",
  // checkedNames.value=[],
  // city.value=""
  data.value.nickName = ''

  data.value.nickName = "",
    data.value.sex = "",
    data.value.checkedNames = [],
    data.value.city = ""
}

//打印模拟接收到的数据
function longds() {
  console.log(res.data);

  console.log(data.value);


}

//用户信息集合的方法

function userInfo() {
  return `用户昵称${data.value.nickName},  性别：${data.value.sex}    爱好：${data.value.checkedNames}    城市：${data.value.city}`
}

//计算机制  //性能更好，依赖的值没有发生改变，则不会重新计算
// 需要根据现有数据派生出一些状态：例如，根据两个输入字段计算总和。
// 需要进行性能优化：避免在模板或方法中重复进行的相同计算。
// 需要缓存复杂计算的结果：如果一个计算结果需要经过多次计算才能得到，使用计算属性可以避免重复计算
//当一个页面需要展示多个变量，并且这些变量之间有关联关系，则可以使用计算属性

let userInfoss = computed(() => {
  console.log("计算属性被调用了");
  return `用户昵称${data.value.nickName},  性别：${data.value.sex}    爱好：${data.value.checkedNames}    城市：${data.value.city}`
})



//监听器
//当某些变量达到了一定的条件，需要执行某些操作时，可以使用监听器
//如果需要监听一个变量，当这个变量的值发生变化时，执行某些操作，可以使用监听器
//监听器可以监听一个变量，也可以监听多个变量
//监听器可以监听一个变量的值，也可以监听一个变量的引用
//监听器可以监听一个变量的值的变化，也可以监听一个变量的引用的变化
//例如：电商购物车的数量，当数量发生变化时，需要重新计算总价，和购物车的加减按钮

let count = ref(0)

//用来控制加减是否显示
let isShowSub = true
let isShowadd = false

// 简便
let isShowSubs = true
let isShowadds = false




//添加按钮点击事件
function add() {
  count.value++
}

//减少按钮点击事件
function sub() {
  count.value--
}

//监听count的值的变化
// watch(count,(newvalue,oldvalue)=>{

//   if(newvalue>0&&newvalue<10){
//     isShowSub=false
//     isShowadd=false
//   }
//   if(newvalue<=0){
//     // alert(newvalue+'小于0，不能减少')
//     console.log(newvalue+'小于0，不能减少')
//     isShowSub=true
//   }
//   if(newvalue>=10){
//     // alert(newvalue+'新的数已经超过10了')
//     console.log(newvalue+'新的数已经超过10了')
//     isShowadd=true
//   }
//   // console.log(`新的值是${newvalue},旧的值是${oldvalue}`);
// })


watch(count, (newvalue, oldvalue) => {
  if (newvalue <= 0) {
    isShowSubs = true
    console.log(newvalue + '小于0，不能减少')

  }
  if (newvalue >= 10) {
    isShowadds = true
  }
  if (newvalue > 0 && newvalue < 10) {
    isShowadds = false
    isShowSubs = false

  }
})


//父亲向子组件传值
//在标签上添加属性，属性名就是子组件中props中的属性名，属性值就是父组件中定义的变量名


//拿到子组件的数据
let childDatas = ref();

// console.log(childDatas.value[1])

// 通过点击按钮方法拿到子组件已经渲染出来的的数据
function getchildDatas() {
  console.log('我是子组件的数据', childDatas.value);
  console.log(childDatas.value.jiangbao.nickName);
}


//路由
// 安装：npm install vue-router@4

let rotuer = useRouter();//获取qu路由对象
console.log('路由对象', rotuer);

//通过路由对象来切换路由地址
function toNotice() {
  rotuer.push('/notice');//切换到notice路由
  // rotuer.replace('/notice');//正常切换路由，覆盖上一层路由，不能回退

}


// Pinia   状态管理
// 使用pinia储存员工id
// let  employeeId='asfsfasf2323232r';

// let useEmployeeStroe= defineStore('emploeeId',{//emploeeId只是一个key，不是上面的变量值
//   state:()=>{
//     return {
//       employeeId,
//       name:'zs'
//     }
//   }
// })
// console.log('pinia',employeeId);

// //获取store
// console.log('定义store的返回值',useEmployeeStroe());

// let store1= useEmployeeStroe();
// console.log('定义store的返回值',store1);
// console.log('定义store的返回值',store1.employeeId);
// store1.name='lisi'//可以直接修改赋值
// console.log('定义store的返回值',store1.name);


// //从EmploeyeeStore.ts文件引入  useEmploeyeeStorestore
import { useEmploeyeeStore } from './employeeStore'
let store = useEmploeyeeStore();
console.log('store', store);
console.log('store', store.getName);
console.log('store', store.getLoginTime);
console.log('store', store.addCount());
console.log('store', store.count);


//axios
// 1、什么是axios?
// Axios 是一个基于 promise 的网络请求库，可以用于浏览器和 node.js中。
// Axios（相比于原生的XMLHttpRequest对象来说）简单易用,（相比于jQuery）axios包尺寸小且提供了易于扩展的接口，是专注于网络请求的库。
// axios（ajax i/o system）不是一种新技术，本质上也是对原生XHR（XMLHttpReques）的封装，只不过它是基于Promise的，是Promise的实现版本，符合最新的ES规范。
// 2、axios和ajax的区别?
// axios是通过promise实现对ajax技术的一种封装，而ajax则是实现了网页的局部数据刷新。
// axios可以说是ajax，而ajax不止是axios。
// 用法相同，但个别参数不同。
import axios from 'axios';

//axios的基础用法
// axios({
//     url: '/demo.json',//请求的地址
//     method: 'get',
//     responseType: 'json', // 默认的
//     data: {
//         name: 'tom'
//     }
// }).then(function (res) {
//     console.log(res);
//     console.log(res.data);
// }).catch(function (error) {
//     console.log(error);
// });


// axios.get('/demo.json',{//[]中括号可以省略、config是基本参数、then是成功回调、catch是失败回调
//   params: {
//         name: 'tom'
//     }
// });


// 6、axios的进阶用法

// let instance = axios.create({
//   // 创建实例时设置配置默
//   baseURL: "http:", //请求的域名/基本地址
//   timeout: 2000, //请求的超时时长，单位毫秒，默认。
//   url: "/data.json", //请求路径
//   method: "get", //请求方法
//   headers: {
//     //设置请求头————我们可以给请求头添加一些参数
//     token: "",
//     post: {
//        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
//     }
//   },
//   params: { id: 5 }, //将请求参数拼接到url上
//   // data: { id: 3 }, //将请求参数放置到请求体里
// });

// var instance = axios.create({
//   baseURL:"https://some-domain.com/api/",//请求的基础地址,url会拼接在baseURL后面
//   timeout:1000,                           //请求超时时间,超过1秒就会报错
//   headers: {'X-Custom-Header':'foobar'}   //请求头放东西，可以放token等
// });

// instance.get('/a.json',{
//     params: { sss: 33 }, //将请求参数拼接到url上
// }).then()

// instance.post('/a.json',{
//     params: { sss: 33 }, //将请求参数拼接到url上
// }).then()


///请求拦截器
// 添加请求拦截器
axios.interceptors.request.use(function (config) {

  // 在发送请求之前做些什么

  return config;
}, function (error) {

  // 对请求错误做些什么

  return Promise.reject(error);
});




//响应拦截器
// 添加响应拦截器
axios.interceptors.response.use(function (response) {//response:响应数据

  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么

  return response;
}, function (error) {

  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么

  return Promise.reject(error);
});

//配置与移除拦截器
// 添加请求拦截器
// const myInterceptor = axios.interceptors.request.use(function () {/*...*/});

// 移除请求拦截器
// axios.interceptors.request.eject(myInterceptor)


import { post, get } from '@/network/index.js'
get('/demo.json',
  {
    zhangsan: 'zangs'
  })
post('/demo.json',
  {
    zhangsan: 'zangs'
  })

</script>

<!-- 样式 -->
<style scoped>
.mainContainer {
  font-size: 20px;
  background-color: cornflowerblue;
}

.blackFont {
  color: white;
}

.whiteBackground {
  background-color: black;
  padding: 10px;
}
</style>
